BX = {};

BX.topdoc = $(window.top.document);
BX.inframe = window.top !== window;

BX.goto = function (url, path) {
	if (BX.inframe) {
		BX.content_location(url, path);
		//window.top.window.open(url);
	} else {
		window.location.href = url;
	}
};

BX.open = function (url) {
	window.open(url);
};

BX.show_content_loading = function () {
	$('#content-loading-panel', BX.topdoc).show();
};
BX.hide_content_loading = function () {
	//$('#content-loading-panel', BX.topdoc).show();

	$('#content-loading-panel', BX.topdoc).hide();
	//$('#content-loading-panel', BX.topdoc).hide('fast', 'linear', function () {
	$('#content-iframe', BX.topdoc).fadeIn('fast');
	//});
};

BX.content_location = function (url, path ,title) {
	// 位置:
	//if (path !== false) {
	if (path) {
		//if (!path) {
		//    path = '谁知道呢';
		//}
		$('#nav-position-span', BX.topdoc).text(path);
	}

    if(title){
        BX.add_tab(title,url,'');
        return;
    }else{
        window.location.href = url;
    }
};
BX.add_tab = function(subtitle,url,icon){
    if(!$('#tabs').tabs('exists',subtitle)){
        $('#tabs').tabs('add',{
            title:subtitle,
            content:BX.create_frame(url),
            closable:true,
            icon:icon
        });
    }else{
        $('#tabs').tabs('select',subtitle);
        $('#mm-tabupdate').click();
    }
    BX.close_tab();
};
BX.close_tab = function(){
    /*双击关闭TAB选项卡*/
    $(".tabs-inner").dblclick(function(){
        var subtitle = $(this).children(".tabs-closable").text();
        $('#tabs').tabs('close',subtitle);
    })
    /*为选项卡绑定右键*/
    $(".tabs-inner").bind('contextmenu',function(e){
        $('#mm').menu('show', {
            left: e.pageX,
            top: e.pageY
        });

        var subtitle =$(this).children(".tabs-closable").text();

        $('#mm').data("currtab",subtitle);
        $('#tabs').tabs('select',subtitle);
        return false;
    });
};
//绑定右键菜单事件
BX.close_tab_even = function tabCloseEven()
{
    //刷新
    $('#mm-tabupdate').click(function(){
        var currTab = $('#tabs').tabs('getSelected');
        var url = $(currTab.panel('options').content).attr('src');
        $('#tabs').tabs('update',{
            tab:currTab,
            options:{
                content:BX.create_frame(url)
            }
        })
    })
    //关闭当前
    $('#mm-tabclose').click(function(){
        var currtab_title = $('#mm').data("currtab");
        $('#tabs').tabs('close',currtab_title);
    })
    //全部关闭
    $('#mm-tabcloseall').click(function(){
        $('.tabs-inner span').each(function(i,n){
            var t = $(n).text();
            $('#tabs').tabs('close',t);
        });
    });

    //关闭除当前之外的TAB
    $('#mm-tabcloseother').click(function(){
        var nextall = $('.tabs-selected').nextAll();
        if(nextall.length>0){
            nextall.each(function(i,n){
                var t=$('a:eq(0) span',$(n)).text();
                $('#tabs').tabs('close',t);
            });
        }
        var prevall = $('.tabs-selected').prevAll();
        if(prevall.length>0){
            prevall.each(function(i,n){
                var t=$('a:eq(0) span',$(n)).text();
                $('#tabs').tabs('close',t);
            });
        }
        $('#mm').menu('hide');
        return false
    });
    //退出
    $("#mm-exit").click(function(){
        $('#mm').menu('hide');
    })
};
BX.content_refresh = function () {
	BX.show_content_loading();
	$('#content-iframe', BX.topdoc).attr('src', $('#content-iframe', BX.topdoc).attr('src'));
	//$('#content-iframe', BX.topdoc).window.location.reload(true);
};
BX.create_frame = function (url) {
    var s = '<iframe scrolling="yes" frameborder="0"  src="'+url+'" style="display:block;width:100%;height:100%;"></iframe>';
    return s;
};

// 设置表单默认label宽度
BX.set_labelWidth = function (labelWidth) {
	$.fn.textbox.defaults.labelWidth = labelWidth;
	$.fn.combo.defaults.labelWidth = labelWidth;
	$.fn.combobox.defaults.labelWidth = labelWidth;
	$.fn.combotree.defaults.labelWidth = labelWidth;
	$.fn.combogrid.defaults.labelWidth = labelWidth;
	$.fn.combotreegrid.defaults.labelWidth = labelWidth;
	$.fn.passwordbox.defaults.labelWidth = labelWidth;
	$.fn.datebox.defaults.labelWidth = labelWidth;
	$.fn.datetimebox.defaults.labelWidth = labelWidth;
	$.fn.datetimespinner.defaults.labelWidth = labelWidth;
	$.fn.filebox.defaults.labelWidth = labelWidth;
	$.fn.numberbox.defaults.labelWidth = labelWidth;
	$.fn.numberspinner.defaults.labelWidth = labelWidth;
};
// 设置表单输入项默认宽度
BX.set_inputWidth = function (width) {
	// 默认宽度
	$.fn.textbox.defaults.width = width;
	$.fn.datebox.defaults.width = width;
	$.fn.filebox.defaults.width = width;
	$.fn.datetimebox.defaults.width = width;
	$.fn.datetimespinner.defaults.width = width;
	$.fn.passwordbox.defaults.width = width;
	$.fn.combo.defaults.width = width;
	$.fn.combobox.defaults.width = width;
	$.fn.combotree.defaults.width = width;
	$.fn.combogrid.defaults.width = width;
	$.fn.numberbox.defaults.width = width;
	$.fn.numberspinner.defaults.width = width;
};
// datebox转换为年月选择框
BX.monthbox = function (db) {
	//var db = $('#db');
	db.datebox({
		onShowPanel: function () {//显示日趋选择对象后再触发弹出月份层的事件，初始化时没有生成月份层
			span.trigger('click'); //触发click事件弹出月份层
			//fix 1.3.x不选择日期点击其他地方隐藏在弹出日期框显示日期面板
			if (p.find('div.calendar-menu').is(':hidden')) p.find('div.calendar-menu').show();
			if (!tds) setTimeout(function () {//延时触发获取月份对象，因为上面的事件触发和对象生成有时间间隔
				tds = p.find('div.calendar-menu-month-inner td');
				tds.click(function (e) {
					e.stopPropagation(); //禁止冒泡执行easyui给月份绑定的事件
					var year = /\d{4}/.exec(span.html())[0]//得到年份
						, month = parseInt($(this).attr('abbr'), 10); //月份，这里不需要+1
					db.datebox('hidePanel')//隐藏日期对象
						.datebox('setValue', year + '-' + month); //设置日期的值
				});
			}, 0);
			yearIpt.unbind();//解绑年份输入框中任何事件
		},
		parser: function (s) {
			if (!s) return new Date();
			var arr = s.split('-');
			return new Date(parseInt(arr[0], 10), parseInt(arr[1], 10) - 1, 1);
		},
		formatter: function (d) {
			if (d.getMonth() < 9) {
				return d.getFullYear() + '-0' + (d.getMonth() + 1);
			} else {
				return d.getFullYear() + '-' + (d.getMonth() + 1);
			}

			/*getMonth返回的是0开始的，忘记了。。已修正*/
		}
	});
	var p = db.datebox('panel'), //日期选择对象
		tds = false, //日期选择对象中月份
		aToday = p.find('a.datebox-current'),
		yearIpt = p.find('input.calendar-menu-year'),//年份输入框
		//显示月份层的触发控件
		span = aToday.length ? p.find('div.calendar-title span') ://1.3.x版本
			p.find('span.calendar-text'); //1.4.x版本
	if (aToday.length) {//1.3.x版本，取消Today按钮的click事件，重新绑定新事件设置日期框为今天，防止弹出日期选择面板

		aToday.unbind('click').click(function () {
			var now = new Date();
			db.datebox('hidePanel').datebox('setValue', now.getFullYear() + '-' + (now.getMonth() + 1));
		});
	}
};

BX.formatter = {
	/**
	 * 格式化时间戳(秒)
	 * @param time
	 * @param fmt
	 * @returns {string}
	 */
	formatTime: function (time, fmt) {
		if (!time || time <= 0) {
			return "";
		}
		if (!fmt) {
			fmt = "yyyy-MM-dd HH:mm:ss";
		}

		var date = new Date();
		date.setTime(time * 1000);
		return date.format(fmt);
	},

	formatTimeFunc: function(value) {
		return BX.formatter.formatTime(value);
	},

	/**
	 * Convert number of bytes into human readable format
	 *
	 * @param number bytes     Number of bytes to convert
	 * @param number precision Number of digits after the decimal separator
	 * @return string
	 */
	bytesToSize: function (bytes, precision) {
		var kilobyte = 1024;
		var megabyte = kilobyte * 1024;
		var gigabyte = megabyte * 1024;
		var terabyte = gigabyte * 1024;

		if ((bytes >= 0) && (bytes < kilobyte)) {
			return bytes + ' B';

		} else if ((bytes >= kilobyte) && (bytes < megabyte)) {
			return (bytes / kilobyte).toFixed(precision) + ' KB';

		} else if ((bytes >= megabyte) && (bytes < gigabyte)) {
			return (bytes / megabyte).toFixed(precision) + ' MB';

		} else if ((bytes >= gigabyte) && (bytes < terabyte)) {
			return (bytes / gigabyte).toFixed(precision) + ' GB';

		} else if (bytes >= terabyte) {
			return (bytes / terabyte).toFixed(precision) + ' TB';

		} else {
			return bytes + ' B';
		}
	},

	formatMoney: function (money, precision) {
		if (precision == undefined) {
			precision = 2;
		}
		if (money !== undefined) {
			return Number(money / 100).toFixed(precision);
		} else {
			return '';
		}
	},

	formatMoneyFunc: function (value) {
		return BX.formatter.formatMoney(value, 2);
	},

	append: function (str, subfix) {
		if (str) {
			return str + subfix;
		}
		return '';
	},

	formatRateFunc: function (value) {
		return BX.formatter.append(value, '%');
	}

};

BX.datagrid = {
	loader: function (setting) {
		return function (param, success_callback, error_callback) {
			// 取得查询参数
			var search_params = $(setting.search_form).serializeObject();
			param = $.extend({}, param, search_params);

			return datagrid_loader({
				url: setting.url,
				param: param,
				success_callback: success_callback,
				error_callback: error_callback
			});
		}
	}
};

/** * 对Date的扩展，将 Date 转化为指定格式的String * 月(M)、日(d)、12小时(h)、24小时(H)、分(m)、秒(s)、周(E)、季度(q)
 可以用 1-2 个占位符 * 年(y)可以用 1-4 个占位符，毫秒(S)只能用 1 个占位符(是 1-3 位的数字) * eg: * (new
 Date()).format("yyyy-MM-dd hh:mm:ss.S")==> 2006-07-02 08:09:04.423
 * (new Date()).format("yyyy-MM-dd E HH:mm:ss") ==> 2009-03-10 二 20:09:04
 * (new Date()).format("yyyy-MM-dd EE hh:mm:ss") ==> 2009-03-10 周二 08:09:04
 * (new Date()).format("yyyy-MM-dd EEE hh:mm:ss") ==> 2009-03-10 星期二 08:09:04
 * (new Date()).format("yyyy-M-d h:m:s.S") ==> 2006-7-2 8:9:4.18
 */
Date.prototype.format = function (fmt) {
	var o = {
		"M+": this.getMonth() + 1, //月份
		"d+": this.getDate(), //日
		"h+": this.getHours() % 12 == 0 ? 12 : this.getHours() % 12, //小时
		"H+": this.getHours(), //小时
		"m+": this.getMinutes(), //分
		"s+": this.getSeconds(), //秒
		"q+": Math.floor((this.getMonth() + 3) / 3), //季度
		"S": this.getMilliseconds() //毫秒
	};
	var week = {
		"0": "/u65e5",
		"1": "/u4e00",
		"2": "/u4e8c",
		"3": "/u4e09",
		"4": "/u56db",
		"5": "/u4e94",
		"6": "/u516d"
	};
	if (/(y+)/.test(fmt)) {
		fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
	}
	if (/(E+)/.test(fmt)) {
		fmt = fmt.replace(RegExp.$1, ((RegExp.$1.length > 1) ? (RegExp.$1.length > 2 ? "/u661f/u671f" : "/u5468") : "") + week[this.getDay() + ""]);
	}
	for (var k in o) {
		if (new RegExp("(" + k + ")").test(fmt)) {
			fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
		}
	}
	return fmt;
};

//var date = new Date();
//window.alert(date.format("yyyy-MM-dd hh:mm:ss"));


String.prototype.addParam = function (params) {
	return this + (/\?/.test(this) ? '&' : '?') + $.param(params);
};

(
	//
	function ($) {
		// 修复jQuery取表单name重名的字段只获取第一个的问题
		$.fn.serializeObject = function () {
			var o = {};
			var a = this.serializeArray();
			$.each(a, function () {
				if (o[this.name] !== undefined) {
					if (!o[this.name].push) {
						o[this.name] = [o[this.name]];
					}
					o[this.name].push(this.value || '');
				} else {
					o[this.name] = this.value || '';
				}
			});
			return o;
		};

		// 修改一些默认值

		//closed:true,width:280,height:320,inline:true,border:'thick',shadow:true,minimizable:false,modal:true,collapsible:false,

		$.extend($.fn.window.defaults, {
			closed: true,
			inline: true,
			border: 'thick',
			shadow: true,
			modal: true,
			minimizable: false,
			collapsible: false
		});

		$.extend($.fn.combo.defaults, {
			panelHeight: 'auto',
			panelMaxHeight: '200px'
		});
		$.extend($.fn.combobox.defaults, {
			panelHeight: 'auto',
			panelMaxHeight: '200px'
		});


		$.fn.combobox.defaults.editable = false;
		$.fn.combobox.defaults.method = 'get';
		$.fn.combotree.defaults.editable = false;

		var default_width = '100%';
		BX.set_inputWidth(default_width);

		$.fn.tree.defaults.method = 'get';

		// 结束

		//扩展easyui中tabs的部分方法，实现根据唯一标识id的进行相应操作；技巧：使用一个自执行的函数，激发作用域，避免这里定义的变量与系统全局变量冲突
		var _methods = $.fn.tabs.methods;
		var _exists = _methods.exists;//保存原方法
		var _getTab = _methods.getTab;//保存原方法
		$.extend($.fn.tabs.methods, {
			getTab: function (jq, which) {//重写getTab方法，增加根据id获取tab（注意：这里我们可以定义任意的获取方式，不必一定使用id）
				if (!which) return null;
				var tabs = jq.data('tabs').tabs;
				for (var i = 0; i < tabs.length; i++) {
					var tab = tabs[i];
					if (tab.panel("options").id == which) {
						return tab;
					}
				}
				return _getTab(jq, which);//如果根据id无法获取，则通过easyui默认的getTab进行获取
			},
			exists: function (jq, which) {//重写exists方法，增加id判断
				return this.getTab(jq, which) != null;//调用重写后的getTab方法
			}
		});

		// 防止panel,dialog,window超出父元素边界
		// http://www.easyui.info/archives/430.html

		$.fn.panel.defaults.constrain = true;
		$.fn.window.defaults.constrain = true;
		$.fn.dialog.defaults.constrain = true;

		$.fn.filebox.defaults.buttonText = '选择文件';

		//$.fn.panel.defaults.border = false;
		$.fn.layout.defaults.border = false;
		$.fn.layout.paneldefaults.border = false;

		var grid_default = {
			loadMsg: '数据加载中。。。',
			emptyMsg: '查无数据',
			pageSize: 20,
			pageList: [10, 20, 30, 40, 50, 100],
			multiSort: true,
			remoteSort: true,
			//fitColumns:false,
			autoRowHeight: false
		};

		$.fn.datagrid.defaults = $.extend({}, $.fn.datagrid.defaults, grid_default);

		$.extend($.fn.combotree.methods, {
			checkAll: function (jq) {
				return jq.each(function () {
					//console.log(this);
					// XXX 全选实现方式, 重新请求数据比js实现快得多
					var old_url = $.data(this, "combotree").options.url;
					var new_url = old_url.addParam({select_all: true});
					$(this).combotree('reload', new_url);
					$.data(this, "combotree").options.url = old_url;
				});
			},
			/**
			 * tree扩展反选
			 */
			uncheckAll: function (jq) {
				return jq.each(function () {
					$(this).combotree('clear');
				});
			}
		});

		//$.fn.datagrid.methods.autoSizeColumn=function(){};
		//var old_func = $.fn.datagrid.methods.autoSizeColumn;
		//$.fn.datagrid.methods.autoSizeColumn = function (jq, _804) {
		//    return old_func(jq, false);
		//};
		//$.fn.combotreegrid.defaults


// form增加禁止方法
// http://www.jeasyui.com/forum/index.php?topic=3038.0
		$.extend($.fn.form.methods, {
			disable: function (jq) {
				return jq.each(function () {
					var t = $(this);
					t.find('input')._propAttr('disabled', 'disabled');
					var plugins = ['textbox', 'combo', 'combobox', 'combotree', 'combogrid', 'datebox', 'datetimebox', 'spinner', 'timespinner', 'numberbox', 'numberspinner', 'slider'];
					for (var i = 0; i < plugins.length; i++) {
						var plugin = plugins[i];
						var r = t.find('.' + plugin + '-f');
						if (r.length && r[plugin]) {
							r[plugin]('disable');
						}
					}
					t.form('validate');
				})
			},
			enable: function (jq) {
				return jq.each(function () {
					var t = $(this);
					t.find('input').removeProp('disabled');
					var plugins = ['textbox', 'combo', 'combobox', 'combotree', 'combogrid', 'datebox', 'datetimebox', 'spinner', 'timespinner', 'numberbox', 'numberspinner', 'slider'];
					for (var i = 0; i < plugins.length; i++) {
						var plugin = plugins[i];
						var r = t.find('.' + plugin + '-f');
						if (r.length && r[plugin]) {
							r[plugin]('enable');
						}
					}
					t.form('validate');
				})
			}
		});

		var _parseJSON = $.parseJSON;

		$.extend({
			parseJSON:function(data){
				if (typeof(data) == 'object') {
					return data;
				}
				return _parseJSON( data );
			}
		});
	}
//
)
(jQuery);

// 让combotree支持搜索
//http://www.dongcoder.com/detail-175009.html
//http://www.cnblogs.com/huangf714/p/5918702.html
(function ($) {
//combotree可编辑，自定义模糊查询
	//$.fn.combotree.defaults.editable = true;
	$.extend($.fn.combotree.defaults.keyHandler, {
		query: function (q) {
			var t = $(this).combotree('tree');
			t.tree("search", q);
		}
	});
	$.extend($.fn.tree.methods, {
		/**
		 * 扩展easyui tree的搜索方法
		 * @param tree easyui tree的根DOM节点(UL节点)的jQuery对象
		 * @param searchText 检索的文本
		 * @param this-context easyui tree的tree对象          */
		search: function (jqTree, searchText) {
//easyui tree的tree对象。可以通过tree.methodName(jqTree)方式调用easyui tree的方法
			var tree = this;
//获取所有的树节点
			var nodeList = getAllNodes(jqTree, tree);
//如果没有搜索条件，则展示所有树节点
			searchText = $.trim(searchText);
			if (searchText == "") {
				for (var i = 0; i < nodeList.length; i++) {
					$(".tree-node-targeted",
						nodeList[i].target).removeClass("tree-node-targeted");
					$(nodeList[i].target).show();
				}
//展开已选择的节点（如果之前选择了）
				var selectedNode = tree.getSelected(jqTree);
				if (selectedNode) {
					tree.expandTo(jqTree, selectedNode.target);
				}
				return;
			}
//搜索匹配的节点并高亮显示
			var matchedNodeList = [];
			if (nodeList && nodeList.length > 0) {
				var node = null;
				for (var i = 0; i < nodeList.length; i++) {
					node = nodeList[i];
					if (isMatch(searchText, node.text)) {
						matchedNodeList.push(node);
					}
				}
//隐藏所有节点
				for (var i = 0; i < nodeList.length; i++) {
					$(".tree-node-targeted", nodeList[i].target).removeClass("tree-node-targeted");
					$(nodeList[i].target).hide();
				}
//折叠所有节点
				tree.collapseAll(jqTree);
//展示所有匹配的节点以及父节点

				for (var i = 0; i < matchedNodeList.length; i++) {
					showMatchedNode(jqTree, tree, matchedNodeList[i]);
				}
			}
		},
		/**
		 * 展示节点的子节点（子节点有可能在搜索的过程中被隐藏了）
		 * @param node easyui tree节点
		 */
		showChildren: function (jqTree, node) {
//easyui tree的tree对象。可以通过tree.methodName(jqTree)方式调用easyui tree的方法
			var tree = this;
//展示子节点
			if (!tree.isLeaf(jqTree, node.target)) {
				var children = tree.getChildren(jqTree, node.target);
				if (children && children.length > 0) {
					for (var i = 0; i < children.length; i++) {
						if ($(children[i].target).is(":hidden")) {
							$(children[i].target).show();
						}
					}
				}
			}
		},
		/**
		 * 将滚动条滚动到指定的节点位置，使该节点可见（如果有滚动条才滚动，没有滚动条就不滚动）
		 * @param param {
		* treeContainer: easyui tree的容器（即存在滚动条的树容器）。如果为null，则取easyui tree的根UL节点的父节点。
		* argetNode:  将要滚动到的easyui tree节点。如果targetNode为空，则默认滚动到当前已选中的节点，如果没有选中的节点，则不滚动          * }             */
		scrollTo: function (jqTree, param) {
//easyui tree的tree对象。可以通过tree.methodName(jqTree)方式调用easyui tree的方法
			var tree = this;
//如果node为空，则获取当前选中的node
			var targetNode = param && param.targetNode ? param.targetNode : tree.getSelected(jqTree);
			if (targetNode != null) {
//判断节点是否在可视区域                 var root = tree.getRoot(jqTree);
				var $targetNode = $(targetNode.target);
				var container = param && param.treeContainer ? param.treeContainer : jqTree.parent();
				var containerH = container.height();
				var nodeOffsetHeight = $targetNode.offset().top - container.offset().top;
				if (nodeOffsetHeight > (containerH - 30)) {
					var scrollHeight = container.scrollTop() + nodeOffsetHeight - containerH + 30;
					container.scrollTop(scrollHeight);
				}
			}
		}
	});

	/**
	 * 展示搜索匹配的节点      */
	function showMatchedNode(jqTree, tree, node) {
//展示所有父节点
		$(node.target).show();
		$(".tree-title", node.target).addClass("tree-node-targeted");
		var pNode = node;
		while ((pNode = tree.getParent(jqTree, pNode.target))) {
			$(pNode.target).show();
		}
//展开到该节点
		tree.expandTo(jqTree, node.target);
//如果是非叶子节点，需折叠该节点的所有子节点
		if (!tree.isLeaf(jqTree, node.target)) {
			tree.collapse(jqTree, node.target);
		}
	}

	/**
	 * 判断searchText是否与targetText匹配
	 * @param searchText 检索的文本      * @param targetText 目标文本
	 * @return true-检索的文本与目标文本匹配；否则为false.
	 */
	function isMatch(searchText, targetText) {
		return $.trim(targetText) != "" && targetText.indexOf(searchText) != -1;
	}

	/**
	 * 获取easyui tree的所有node节点      */
	function getAllNodes(jqTree, tree) {
		var allNodeList = jqTree.data("allNodeList");
		if (!allNodeList) {
			var roots = tree.getRoots(jqTree);
			allNodeList = getChildNodeList(jqTree, tree, roots);
			jqTree.data("allNodeList", allNodeList);
		}
		return allNodeList;
	}

	/**
	 * 定义获取easyui tree的子节点的递归算法      */
	function getChildNodeList(jqTree, tree, nodes) {
		var childNodeList = [];
		if (nodes && nodes.length > 0) {
			var node = null;
			for (var i = 0; i < nodes.length; i++) {
				node = nodes[i];
				childNodeList.push(node);
				if (!tree.isLeaf(jqTree, node.target)) {
					var children = tree.getChildren(jqTree, node.target);
					childNodeList = childNodeList.concat(getChildNodeList(jqTree, tree, children));
				}
			}
		}
		return childNodeList;
	}
})(jQuery);

(function ($) {
	/**
	 * layout方法扩展
	 * @param {Object} jq
	 * @param {Object} region
	 */
	$.extend($.fn.layout.methods, {
		/**
		 * 面板是否存在和可见
		 * @param {Object} jq
		 * @param {Object} params
		 */
		isVisible: function (jq, params) {
			var panels = $.data(jq[0], 'layout').panels;
			var pp = panels[params];
			if (!pp) {
				return false;
			}
			if (pp.length) {
				return pp.panel('panel').is(':visible');
			} else {
				return false;
			}
		},
		/**
		 * 隐藏除某个region，center除外。
		 * @param {Object} jq
		 * @param {Object} params
		 */
		hidden: function (jq, params) {
			return jq.each(function () {
				var opts = $.data(this, 'layout').options;
				var panels = $.data(this, 'layout').panels;
				if (!opts.regionState) {
					opts.regionState = {};
				}
				var region = params;

				function hide(dom, region, doResize) {
					var first = region.substring(0, 1);
					var others = region.substring(1);
					var expand = 'expand' + first.toUpperCase() + others;
					if (panels[expand]) {
						if ($(dom).layout('isVisible', expand)) {
							opts.regionState[region] = 1;
							panels[expand].panel('close');
						} else if ($(dom).layout('isVisible', region)) {
							opts.regionState[region] = 0;
							panels[region].panel('close');
						}
					} else {
						panels[region].panel('close');
					}
					if (doResize) {
						$(dom).layout('resize');
					}
				};
				if (region.toLowerCase() == 'all') {
					hide(this, 'east', false);
					hide(this, 'north', false);
					hide(this, 'west', false);
					hide(this, 'south', true);
				} else {
					hide(this, region, true);
				}
			});
		},
		/**
		 * 显示某个region，center除外。
		 * @param {Object} jq
		 * @param {Object} params
		 */
		show: function (jq, params) {
			return jq.each(function () {
				var opts = $.data(this, 'layout').options;
				var panels = $.data(this, 'layout').panels;
				var region = params;

				function show(dom, region, doResize) {
					var first = region.substring(0, 1);
					var others = region.substring(1);
					var expand = 'expand' + first.toUpperCase() + others;
					if (panels[expand]) {
						if (!$(dom).layout('isVisible', expand)) {
							if (!$(dom).layout('isVisible', region)) {
								if (opts.regionState[region] == 1) {
									panels[expand].panel('open');
								} else {
									panels[region].panel('open');
								}
							}
						}
					} else {
						panels[region].panel('open');
					}
					if (doResize) {
						$(dom).layout('resize');
					}
				};
				if (region.toLowerCase() == 'all') {
					show(this, 'east', false);
					show(this, 'north', false);
					show(this, 'west', false);
					show(this, 'south', true);
				} else {
					show(this, region, true);
				}
			});
		}
	});

	/**
	 * layout方法扩展
	 */
	$.extend($.fn.layout.methods, {
		setRegionToolVisableState: function (jq, params) {
			return jq.each(function () {
				if (params.region == "center")
					return;
				var panels = $.data(this, 'layout').panels;
				var panel = panels[params.region];
				var tool = panel.panel('header').find('>div.panel-tool');
				tool.css({display: params.visible ? 'block' : 'none'});
				var first = params.region.substring(0, 1);
				var others = params.region.substring(1);
				var expand = 'expand' + first.toUpperCase() + others;
				if (panels[expand]) {
					panels[expand].panel('header').find('>div.panel-tool').css({display: params.visible ? 'block' : 'none'});
				}
			});
		}
	});
})(jQuery);

/**
 * 将表单转换为k=>v结构
 * @returns {Object}
 */
jQuery.prototype.serializeObject = function () {
	var obj = {};
	$.each(this.serializeArray(), function (index, param) {
		if (!(param.name in obj)) {
			obj[param.name] = param.value;
		}
	});
	return obj;
};

function datagrid_loader(settings) {
	//console.log('load');
	// 参考 http://www.w3school.com.cn/jquery/ajax_ajax.asp
	//console.log(settings);
	//
	var opts = {
		method: 'get',
		param: {}
	};

	try {
		opts = $(this).datagrid("options");
		//console.log(opts);
	} catch (e) {

	}

	opts = $.extend({}, opts, settings);

	//console.log(opts);
	if (!opts.param) {
		opts.param = {};
	}

	//opts.param._csrf = $('meta[name="csrf-token"]').attr("content");

	if (!opts.url) {
		return false;
	}

	// 处理排序, 将id移动到末尾
	if (opts.param.sort && opts.param.order) {
		var sorts = opts.param.sort.split(",");
		var orders = opts.param.order.split(",");

		if (sorts && sorts.length > 1 && sorts[0] && (sorts[0] == 'id' || sorts[0].indexOf('.id') > 0)) {
			var old_sort = sorts[0];
			var old_order = orders[0];

			sorts.splice(0, 1);
			orders.splice(0, 1);

			sorts.push(old_sort);
			orders.push(old_order);

			opts.param.sort = sorts.join(',');
			opts.param.order = orders.join(',');
		}
	}

	$.ajax(
		{
			url: opts.url,
			method: opts.method,
			cache: false,
			data: opts.param,
			dataType: 'json',
			async: true,
			//timeout: 10000, // 10s
			success: function (data) {
				if (data['type'] == 'error') {
					opts.error_callback.apply(this);

					$.messager.alert('错误', data['message'], 'error', function () {
						if (data['redirect_url']) {
							top.location.href = data['redirect_url'];
						}
					});
				} else {
					opts.success_callback(data);
				}
			},
			error: function (xhr, msg, err) {
				var msgcn = '发生错误';

				if (msg == 'parsererror') {
					msgcn = '数据解析错误';
				} else if (msg == 'timeout') {
					msgcn = '超时';
				} else if (msg == 'notmodified') {
					msgcn = '缓存';
				} else if (msg == 'error') {

				} else {
					msgcn = '未知错误';
				}

				$.messager.alert('错误', msgcn, 'error');
				opts.error_callback.apply(this);

				console.log('ajax error', {url: opts.url, data: opts.param, msg: msg, err: err});
			}
		});
	return true;
};

// 扩展验证规则
//http://www.cnblogs.com/Lxiaojiang/p/5928872.html
$(function () {
//设置text需要验证
//    $('input[type=text]').validatebox();
//自定义validator.js
//扩展easyui表单的验证
	$.extend($.fn.validatebox.defaults.rules, {

		// 密码框验证规则
		confirmPass: {
			validator: function (value, param) {
				var pass = $(param[0]).passwordbox('getValue');
				return value == pass;
			},
			message: '\u4e24\u6b21\u5bc6\u7801\u8f93\u5165\u4e0d\u4e00\u81f4'
		},

//1.验证汉字
		CHS: {
			validator: function (value) {
				return /^[\u0391-\uFFE5]+$/.test(value);
			},
			message: '只能输入汉字'
		},

//2.移动手机号码验证
		mobile: {//value值为文本框中的值
			validator: function (value) {
				var reg = /^1[3|4|5|7|8|9]\d{9}$/;
				return reg.test(value);
			},
			message: '输入手机号码格式不正确'
		},

//3.电话号码验证
		phone: {// 验证电话号码

			validator: function (value) {
				return /^((\d{2,3})|(\d{3}\-))?(0\d{2,3}|0\d{2,3}-)?[1-9]\d{6,7}(\-\d{1,4})?$/i.test(value);
			},
			message: '格式不正确,请使用下面格式:020-88888888'
		},


//4.验证IP
		ip: {// 验证IP地址
			validator: function (value) {
				return /\d+\.\d+\.\d+\.\d+/.test(value);
			},
			message: 'IP地址格式不正确'
		},


// 5.验证姓名，可以是中文或英文

		name: {
			validator: function (value) {
				return /^[\Α-\￥]+$/i.test(value) | /^\w+[\w\s]+\w+$/i.test(value);
			},
			message: '请输入姓名'
		},


// 6.验证用户名，可以是中文或英文
		username: {// 验证用户名
			validator: function (value) {
				return /^[a-zA-Z][a-zA-Z0-9_]{5,15}$/i.test(value);
			},
			message: '用户名不合法（字母开头，允许6-16字节，允许字母数字下划线）'
		},


// 7.验证日期
		date: {// 验证日期
			validator: function (value) {
//格式yyyy-MM-dd或yyyy-M-d
				return /^(?:(?!0000)[0-9]{4}([-]?)(?:(?:0?[1-9]|1[0-2])\1(?:0?[1-9]|1[0-9]|2[0-8])|(?:0?[13-9]|1[0-2])\1(?:29|30)|(?:0?[13578]|1[02])\1(?:31))|(?:[0-9]{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)([-]?)0?2\2(?:29))$/i.test(value);
			},
			message: '清输入合适的日期格式'
		},


// 8.验证英语

		english: {// 验证英语
			validator: function (value) {
				return /^[A-Za-z]+$/i.test(value);
			},
			message: '请输入英文'
		},


//9.国内邮编验证
		zipcode: {
			validator: function (value) {
				var reg = /^[1-9]\d{5}$/;
				return reg.test(value);
			},
			message: '邮编必须是非0开始的6位数字.'
		},

// 10.验证身份证
		idcard: {// 验证身份证
			validator: function (value) {
				return /^\d{15}(\d{2}[A-Za-z0-9])?$/i.test(value);
			},
			message: '身份证号码格式不正确'
		},

// 11.验证最小长度
		minLength: {
			validator: function (value, param) {
				return value.length >= param[0];
			},
			message: '请输入至少（2）个字符.'
		},

// 12.验证整数还是小数
		intOrFloat: {// 验证整数或小数
			validator: function (value) {
				return /^\d+(\.\d+)?$/i.test(value);
			},
			message: '请输入数字，并确保格式正确'
		},

// 13.验证QQ
		qq: {// 验证QQ,从10000开始
			validator: function (value) {
				return /^[1-9]\d{4,9}$/i.test(value);
			},
			message: 'QQ号码格式不正确'
		},
// 14.验证整数 可正负数
		integer: {// 验证整数 可正负数
			validator: function (value) {
				return /^[+]?[1-9]+\d*$/i.test(value);

//return /^([+]?[0-9])|([-]?[0-9])+\d*$/i.test(value);
			},
			message: '请输入整数'
		},

// 15.验证年龄
		age: {// 验证年龄
			validator: function (value) {
				return /^(?:[1-9][0-9]?|1[01][0-9]|120)$/i.test(value);
			},
			message: '年龄必须是0到120之间的整数'
		},


//16.验证是否包含非法字符
		unnormal: {// 验证是否包含空格和非法字符
			validator: function (value) {
				return /.+/i.test(value);
			},
			message: '输入值不能为空和包含其他非法字符'
		},

//17.验证传真
		faxno: {// 验证传真
			validator: function (value) {
// return /^[+]{0,1}(\d){1,3}[ ]?([-]?((\d)|[ ]){1,12})+$/i.test(value);
				return /^((\d{2,3})|(\d{3}\-))?(0\d{2,3}|0\d{2,3}-)?[1-9]\d{6,7}(\-\d{1,4})?$/i.test(value);
			},
			message: '传真号码不正确'
		},

//18.验证数字

		number: {
			validator: function (value, param) {
				return /^[0-9]+.?[0-9]*$/.test(value);
			},
			message: '请输入数字'
		},

//19.验证密码两次的输入是否相同
		same: {
			validator: function (value, param) {
				if ($("#" + param[0]).val() != "" && value != "") {
					return $("#" + param[0]).val() == value;
				} else {
					return true;
				}
			},
			message: '两次输入的密码不一致！'
		},

//20.验证车牌号码
		carNo: {
			validator: function (value) {
				return /^[\u4E00-\u9FA5][\da-zA-Z]{6}$/.test(value);
			},
			message: '车牌号码无效（例：粤B12350）'
		},

//21.用户账号验证(只能包括 _ 数字 字母)
		account: {//param的值为[]中值
			validator: function (value, param) {
				if (value.length < param[0] || value.length > param[1]) {
					$.fn.validatebox.defaults.rules.account.message = '用户名长度必须在' + param[0] + '至' + param[1] + '范围';
					return false;
				}
				else {
					if (!/^[\w]+$/.test(value)) {
						$.fn.validatebox.defaults.rules.account.message = '用户名只能数字、字母、下划线组成.';
						return false;
					}
					else {
						return true;
					}
				}
			},
			message: ''
		}
	});
});

// https://github.com/didanurwanda/inflector-js/blob/master/index.js
(function () {
	var _Inflector = {

		uncountableWords: [
			'equipment', 'information', 'rice', 'money', 'species', 'series',
			'fish', 'sheep', 'moose', 'deer', 'news'
		],

		pluralRules: [
			[new RegExp('(m)an$', 'gi'), '$1en'],
			[new RegExp('(pe)rson$', 'gi'), '$1ople'],
			[new RegExp('(child)$', 'gi'), '$1ren'],
			[new RegExp('^(ox)$', 'gi'), '$1en'],
			[new RegExp('(ax|test)is$', 'gi'), '$1es'],
			[new RegExp('(octop|vir)us$', 'gi'), '$1i'],
			[new RegExp('(alias|status)$', 'gi'), '$1es'],
			[new RegExp('(bu)s$', 'gi'), '$1ses'],
			[new RegExp('(buffal|tomat|potat)o$', 'gi'), '$1oes'],
			[new RegExp('([ti])um$', 'gi'), '$1a'],
			[new RegExp('sis$', 'gi'), 'ses'],
			[new RegExp('(?:([^f])fe|([lr])f)$', 'gi'), '$1$2ves'],
			[new RegExp('(hive)$', 'gi'), '$1s'],
			[new RegExp('([^aeiouy]|qu)y$', 'gi'), '$1ies'],
			[new RegExp('(x|ch|ss|sh)$', 'gi'), '$1es'],
			[new RegExp('(matr|vert|ind)ix|ex$', 'gi'), '$1ices'],
			[new RegExp('([m|l])ouse$', 'gi'), '$1ice'],
			[new RegExp('(quiz)$', 'gi'), '$1zes'],
			[new RegExp('s$', 'gi'), 's'],
			[new RegExp('$', 'gi'), 's']
		],

		singularRules: [
			[new RegExp('(m)en$', 'gi'), '$1an'],
			[new RegExp('(pe)ople$', 'gi'), '$1rson'],
			[new RegExp('(child)ren$', 'gi'), '$1'],
			[new RegExp('([ti])a$', 'gi'), '$1um'],
			[new RegExp('((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$', 'gi'), '$1$2sis'],
			[new RegExp('(hive)s$', 'gi'), '$1'],
			[new RegExp('(tive)s$', 'gi'), '$1'],
			[new RegExp('(curve)s$', 'gi'), '$1'],
			[new RegExp('([lr])ves$', 'gi'), '$1f'],
			[new RegExp('([^fo])ves$', 'gi'), '$1fe'],
			[new RegExp('([^aeiouy]|qu)ies$', 'gi'), '$1y'],
			[new RegExp('(s)eries$', 'gi'), '$1eries'],
			[new RegExp('(m)ovies$', 'gi'), '$1ovie'],
			[new RegExp('(x|ch|ss|sh)es$', 'gi'), '$1'],
			[new RegExp('([m|l])ice$', 'gi'), '$1ouse'],
			[new RegExp('(bus)es$', 'gi'), '$1'],
			[new RegExp('(o)es$', 'gi'), '$1'],
			[new RegExp('(shoe)s$', 'gi'), '$1'],
			[new RegExp('(cris|ax|test)es$', 'gi'), '$1is'],
			[new RegExp('(octop|vir)i$', 'gi'), '$1us'],
			[new RegExp('(alias|status)es$', 'gi'), '$1'],
			[new RegExp('^(ox)en', 'gi'), '$1'],
			[new RegExp('(vert|ind)ices$', 'gi'), '$1ex'],
			[new RegExp('(matr)ices$', 'gi'), '$1ix'],
			[new RegExp('(quiz)zes$', 'gi'), '$1'],
			[new RegExp('s$', 'gi'), '']
		],

		nonTitlecasedWords: [
			'and', 'or', 'nor', 'a', 'an', 'the', 'so', 'but', 'to', 'of', 'at',
			'by', 'from', 'into', 'on', 'onto', 'off', 'out', 'in', 'over',
			'with', 'for'
		],

		idSuffix: new RegExp('(_ids|_id)$', 'g'),
		underbar: new RegExp('_', 'g'),
		spaceOrUnderbar: new RegExp('[\ _]', 'g'),
		uppercase: new RegExp('([A-Z])', 'g'),
		underbarPrefix: new RegExp('^_'),

		applyRules: function (str, rules, skip, override) {
			if (override) {
				str = override;
			} else {
				var ignore = (skip.indexOf(str.toLowerCase()) > -1);
				if (!ignore) {
					for (var x = 0; x < rules.length; x++) {
						if (str.match(rules[x][0])) {
							str = str.replace(rules[x][0], rules[x][1]);
							break;
						}
					}
				}
			}
			return str;
		},


		/*
		 Inflector.pluralize('person')           -> 'people'
		 Inflector.pluralize('octopus')          -> 'octopi'
		 Inflector.pluralize('Hat')              -> 'Hats'
		 Inflector.pluralize('person', 'guys')   -> 'guys'
		 */
		pluralize: function (str, plural) {
			return this.applyRules(
				str,
				this.pluralRules,
				this.uncountableWords,
				plural
			);
		},

		/*
		 Inflector.singularize('person')         -> 'person'
		 Inflector.singularize('octopi')         -> 'octopus'
		 Inflector.singularize('hats')           -> 'hat'
		 Inflector.singularize('guys', 'person') -> 'person'
		 */
		singularize: function (str, singular) {
			return this.applyRules(
				str,
				this.singularRules,
				this.uncountableWords,
				singular
			);
		},

		/*
		 Inflector.camelize('message_properties')        -> 'MessageProperties'
		 Inflector.camelize('message_properties', true)  -> 'messageProperties'
		 */
		camelize: function (str, lowFirstLetter) {
			// var str = str.toLowerCase();
			var str_path = str.split('/');
			for (var i = 0; i < str_path.length; i++) {
				var str_arr = str_path[i].split('_');
				var initX = ((lowFirstLetter && i + 1 === str_path.length) ? (1) : (0));
				for (var x = initX; x < str_arr.length; x++) {
					str_arr[x] = str_arr[x].charAt(0).toUpperCase() + str_arr[x].substring(1);
				}
				str_path[i] = str_arr.join('');
			}
			str = str_path.join('::');

			// fix
			if (lowFirstLetter === true) {
				var first = str.charAt(0).toLowerCase();
				var last = str.slice(1);
				str = first + last;
			}

			return str;
		},

		/*
		 Inflector.underscore('MessageProperties')       -> 'message_properties'
		 Inflector.underscore('messageProperties')       -> 'message_properties'
		 */
		underscore: function (str) {
			var str_path = str.split('::');
			for (var i = 0; i < str_path.length; i++) {
				str_path[i] = str_path[i].replace(this.uppercase, '_$1');
				str_path[i] = str_path[i].replace(this.underbarPrefix, '');
			}
			str = str_path.join('/').toLowerCase();
			return str;
		},

		/*
		 Inflector.humanize('message_properties')        -> 'Message properties'
		 Inflector.humanize('message_properties')        -> 'message properties'
		 */
		humanize: function (str, lowFirstLetter) {
			var str = str.toLowerCase();
			str = str.replace(this.idSuffix, '');
			str = str.replace(this.underbar, ' ');
			if (!lowFirstLetter) {
				str = this.capitalize(str);
			}
			return str;
		},

		/*
		 Inflector.capitalize('message_properties')      -> 'Message_properties'
		 Inflector.capitalize('message properties')      -> 'Message properties'
		 */
		capitalize: function (str) {
			var str = str.toLowerCase();
			str = str.substring(0, 1).toUpperCase() + str.substring(1);
			return str;
		},

		/*
		 Inflector.dasherize('message_properties')       -> 'message-properties'
		 Inflector.dasherize('message properties')       -> 'message-properties'
		 */
		dasherize: function (str) {
			str = str.replace(this.spaceOrUnderbar, '-');
			return str;
		},

		/*
		 Inflector.camel2words('message_properties')         -> 'Message Properties'
		 Inflector.camel2words('message properties')         -> 'Message Properties'
		 Inflactor.camel2words('Message_propertyId', true)   -> 'Message Properties Id'
		 */
		camel2words: function (str, allFirstUpper) {
			//var str = str.toLowerCase();
			if (allFirstUpper === true) {
				str = this.camelize(str);
				str = this.underscore(str);
			} else {
				str = str.toLowerCase();
			}

			str = str.replace(this.underbar, ' ');
			var str_arr = str.split(' ');
			for (var x = 0; x < str_arr.length; x++) {
				var d = str_arr[x].split('-');
				for (var i = 0; i < d.length; i++) {
					if (this.nonTitlecasedWords.indexOf(d[i].toLowerCase()) < 0) {
						d[i] = this.capitalize(d[i]);
					}
				}
				str_arr[x] = d.join('-');
			}
			str = str_arr.join(' ');
			str = str.substring(0, 1).toUpperCase() + str.substring(1);
			return str;
		},
		id2camel: function (str) {
			return _Inflector.camelize(str.replace(/\-/g, '_'));
		},
		camel2id: function (str) {
			return _Inflector.underscore(str).replace(/_/g, '-');
		},
		/*
		 Inflector.demodulize('Message::Bus::Properties')    -> 'Properties'
		 */
		demodulize: function (str) {
			var str_arr = str.split('::');
			str = str_arr[str_arr.length - 1];
			return str;
		},

		/*
		 Inflector.tableize('MessageBusProperty')    -> 'message_bus_properties'
		 */
		tableize: function (str) {
			str = this.pluralize(this.underscore(str));
			return str;
		},

		/*
		 Inflector.classify('message_bus_properties')    -> 'MessageBusProperty'
		 */
		classify: function (str) {
			str = this.singularize(this.camelize(str));
			return str;
		},

		/*
		 Inflector.foreignKey('MessageBusProperty')       -> 'message_bus_property_id'
		 Inflector.foreignKey('MessageBusProperty', true) -> 'message_bus_propertyid'
		 */
		foreignKey: function (str, dropIdUbar) {
			str = this.underscore(this.demodulize(str)) + ((dropIdUbar) ? ('') : ('_')) + 'id';
			return str;
		},

		/*
		 Inflector.ordinalize('the 1 pitch')     -> 'the 1st pitch'
		 */
		ordinalize: function (str) {
			var str_arr = str.split(' ');
			for (var x = 0; x < str_arr.length; x++) {
				var i = parseInt(str_arr[x]);
				if (i === NaN) {
					var ltd = str_arr[x].substring(str_arr[x].length - 2);
					var ld = str_arr[x].substring(str_arr[x].length - 1);
					var suf = "th";
					if (ltd != "11" && ltd != "12" && ltd != "13") {
						if (ld === "1") {
							suf = "st";
						}
						else if (ld === "2") {
							suf = "nd";
						}
						else if (ld === "3") {
							suf = "rd";
						}
					}
					str_arr[x] += suf;
				}
			}
			str = str_arr.join(' ');
			return str;
		}
	};

	if (typeof exports === "object" && typeof module === "object") {
		module.exports = _Inflector;
	} else if (typeof define === "function" && define.amd) {
		define([], function () {
			return _Inflector;
		});
	} else {
		window.Inflector = _Inflector;
	}
})();